wayland: Thaw the clock if we hide a GdkWindow mid-frame
authorCarlos Garnacho <carlosg@gnome.org>
Wed, 25 Feb 2015 13:46:54 +0000 (14:46 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Mon, 2 Mar 2015 11:11:59 +0000 (12:11 +0100)
When a window is hidden, its surface and all its roles are destroyed,
if this happens when we already issued a wl_surface_commit and are
awaiting for a frame callback, the clock will remain frozen for the
next time the window is shown.

To avoid this, keep track of the wl_surface_frame() calls issued,
and ensure the clock is thawed after hiding. If we happen to receive
the frame callback, it is just ignored.

https://bugzilla.gnome.org/show_bug.cgi?id=743427

gdk/wayland/gdkwindow-wayland.c

index bcfff714f862f60b97020864f06acd43506a7869..3bfbea1a17c81270e00bd173fdd6f56a56d5af01 100644 (file)
@@ -109,6 +109,7 @@ struct _GdkWindowImplWayland
   unsigned int mapped : 1;
   unsigned int use_custom_surface : 1;
   unsigned int pending_commit : 1;
+  unsigned int awaiting_frame : 1;
   GdkWindowTypeHint hint;
   GdkWindow *transient_for;
 
@@ -324,6 +325,10 @@ frame_callback (void               *data,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  if (!impl->awaiting_frame)
+    return;
+
+  impl->awaiting_frame = FALSE;
   _gdk_frame_clock_thaw (clock);
 
   timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter);
@@ -401,6 +406,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
 
   impl->pending_commit = FALSE;
   impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
+  impl->awaiting_frame = TRUE;
 
   callback = wl_surface_frame (impl->surface);
   wl_callback_add_listener (callback, &frame_listener, window);
@@ -1265,6 +1271,12 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
           impl->subsurface = NULL;
         }
 
+      if (impl->awaiting_frame)
+        {
+          impl->awaiting_frame = FALSE;
+          _gdk_frame_clock_thaw (gdk_window_get_frame_clock (window));
+        }
+
       wl_surface_destroy (impl->surface);
       impl->surface = NULL;